package controllers;

import java.io.BufferedReader;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;

import javax.xml.parsers.ParserConfigurationException;

import jobs.DownloadStatus;
import nzb.FileDownloader;
import nzb.NzbFile;
import nzb.NzbParser;

import org.xml.sax.SAXException;

import play.Logger;
import play.Play;
import play.cache.Cache;


public class NzbGrabber extends Thread {

	public  Semaphore			downloadThreadSemaphore;
	public	List<NzbFile> 		fileList;
	public	BufferedReader 		in;
	
	public  ConcurrentLinkedQueue<FileDownloader>	downloadQueue;
	public 	DownloadStatus							downloadStatus;
	
	public	String 				buffer;
	private	Iterator<NzbFile>	fileIterator;
	
	public	Integer				nbFiles;
	public	Integer				fileCount;
	public	Integer				maxDownloadThreads;
	
	public static String	DOWNLOAD_DEST_DIR	= Play.configuration.get("download_destinationdir").toString();

	public NzbGrabber(File nzbFile, Integer maxDownloadThreads) throws Exception {
		this.maxDownloadThreads = maxDownloadThreads;
		downloadThreadSemaphore = new Semaphore(maxDownloadThreads, true);
		Logger.info("Nb Threads disponibles : " + 20);
		
		NzbParser nzbMachine = new NzbParser(nzbFile.getAbsolutePath());
		
		nzbMachine.parse();
		fileList = nzbMachine.getFiles();
		
		fileCount = 0;
		nbFiles = fileList.size();
		
		downloadStatus = (DownloadStatus) Cache.get("DOWNLOAD_STATUS");
		downloadStatus.setTotalNbFiles(nbFiles);
		Cache.set("DOWNLOAD_STATUS", downloadStatus);
		
		fileIterator = fileList.iterator();
		downloadQueue = new ConcurrentLinkedQueue<FileDownloader>();
		
		while(fileIterator.hasNext()) {
			downloadQueue.add(new FileDownloader(this, fileIterator.next()));
		}
	}
	
	public void run() {
//		ExecutorService service = Executors.newFixedThreadPool(1);
		for (FileDownloader downloader : downloadQueue) {
			try {
				Logger.info("Telechargement du fichier " + downloader.currentFile.getFileName());
				downloader.run();
			} catch (Exception e) {
				Logger.error("Erreur lors du telechargement du fichier : " + downloader.currentFile.getFileName(), e);
				e.printStackTrace();
			}
		}
		
//		try {
//			service.shutdown();
//			service.awaitTermination(10, TimeUnit.HOURS);
//		} catch (Exception e) {
//			Logger.error("Erreur sur thread FileDownloader", e);
//		}
		
		this.downloadQueue.clear();
		
		Cache.set("DOWNLOAD_STATUS", null);
		this.uncompress();
		Logger.info("Telechargement termine");
	}
	
	public void uncompress() {
		FilenameFilter rarFilter = new FilenameFilter() {
			@Override
			public boolean accept(File dir, String name) {
				return name.endsWith(".rar");
			}
		};
		
		File destDir = new File(DOWNLOAD_DEST_DIR);
		
		File[] rarFiles = destDir.listFiles(rarFilter);
		for (File rarFile : rarFiles) {
			try {
				Process process = Runtime.getRuntime().exec(Play.applicationPath.getPath() + "\\cmd\\unrar\\unrar.exe e " + DOWNLOAD_DEST_DIR + rarFile.getName() + " " + DOWNLOAD_DEST_DIR);
				String line;
				String line2;
				BufferedReader in = new BufferedReader(
				   new InputStreamReader(process.getInputStream()) );
			       while ((line = in.readLine()) != null) {
			         System.out.println(line);
			       }
			       in.close();
			       BufferedReader in2 = new BufferedReader(
			    		   new InputStreamReader(process.getErrorStream()) );
			       while ((line2 = in2.readLine()) != null) {
			    	   System.out.println(line);
			       }
			       in2.close();
			} catch (Exception e) {
				Logger.error("Une erreur est survenue lors de la décompression du fichier : " + rarFile.getName());
				e.printStackTrace();
			}
		}
	}
}
